/*
 * mftgslicerenderer.h
 *
 *  Created on: 23/07/2012
 *      Author: cvan680
 *
 * Multi-Field Texture Grammar Slice Renderer
 *
 * Renders slices of multiple volumes using our multi-field texture grammar method.
 */

#ifndef CCVEMFTG2D_H_
#define CCVEMFTG2D_H_

#include "voreen/core/processors/imageprocessor.h"
#include "texturegrammar/texturegrammar.h"
#include "tgt/tgt_gl.h"

using tgt::TextureUnit;
using std::string;

namespace voreen {

class MFTGSliceRenderer : public ImageProcessor {

public:
	MFTGSliceRenderer();
	~MFTGSliceRenderer();

    // virtual constructor
    virtual Processor* create() const;

    // documentary functions
    virtual std::string getClassName() const { return "MFTGSliceRenderer";       }
    virtual std::string getCategory() const  { return "Multi-field visualization";      }
    virtual CodeState getCodeState() const   { return CODE_STATE_EXPERIMENTAL; }

protected:
    virtual void setDescriptions() {
        setDescription("Takes one or more volumes (of equal dimensions?), and uses a texture grammar to visualize slices. TODO");
    }

    virtual void process();
    virtual void initialize() throw (VoreenException);
    virtual void deinitialize() throw (VoreenException);

    GLuint createTexture(GLubyte* data, tgt::ivec2 dims, int textype);
    void bindTexture(GLuint id, string uniform, TextureUnit texunit);

private:
/*
    // ports and properties
    RenderPort inport_; // need several (or variable amount)

    FileDialogProperty grammarfile_;
*/

    TextureGrammar* grammar_;

    RenderPort outport_;
    RenderPort privatePort1_;

    void MFTGSliceRenderer::prepareData(tgt::ivec2 vps);
    GLubyte* getData(int fieldindex, tgt::ivec2 vps);

    // methods generating synthetic data fields
    GLubyte* noiseMap(tgt::vec2 dim);
    GLubyte* scalarField(tgt::vec2 dim, int whichfield);
    GLubyte* vectorField(tgt::vec2 dim, int whichfield);
    GLubyte* vectorField01(tgt::vec2 dim);
    GLubyte* vectorField02(tgt::vec2 dim);
    GLubyte* vectorFieldRandom(tgt::vec2 dim);

    GLubyte* arrowPlot(tgt::vec2 dim);
    GLubyte* TEMPstreamLines(tgt::vec2 dim);

    GLubyte* noisemap;
    GLubyte* data1;
    GLubyte* data2;
    GLubyte* data3;
    GLubyte* data4;
    GLubyte* data5;
    GLubyte* data6;
    GLubyte* data7;
    GLubyte* data8;
    GLubyte* data9;
    GLubyte* data10;

    int textype1;
    int textype2;
    int textype3;
    int textype4;
    int textype5;
    int textype6;
    int textype7;
    int textype8;
    int textype9;
    int textype10;

    // FIXME remove
    IntProperty refreshRate;

    int total_fields;
    int current_field;

    int count_scalar_fields;
    int count_vector_fields;

    tgt::vec2 calcVec(tgt::vec2 relcoords, int type);
    enum SingularityType {
    	NONE = 0,
    	NODE = 1,
    	SADDLE = 2,
    	ATTRACTING_FOCUS = 3,
    	REPELLING_FOCUS = 4,
    	CENTER = 5
    };

    // mouse event handling
    EventProperty<MFTGSliceRenderer>* mouseEventProp_;
    EventProperty<MFTGSliceRenderer>* mouseEventProp2_;
    void mouseEvent(tgt::MouseEvent* e);
    void rightClickEvent(tgt::MouseEvent* e);
    tgt::ivec2 mouseCurPos2D_;
    bool mouseDown_;
    int ORIGINAL_COUNTER;
    int counter_;

};

}


#endif /* CCVEMFTG2D_H_ */
